// 为usleep添加必要的定义
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include "rk3588_gpio_pins.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>

// GPIO导出函数
int gpio_export(int pin) {
    char buffer[64];
    int fd, len;
    
    // 检查GPIO是否已经导出
    if (gpio_is_exported(pin)) {
        return 0; // 已经导出
    }
    
    fd = open(GPIO_EXPORT_PATH, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open export for writing\n");
        return -1;
    }
    
    len = snprintf(buffer, sizeof(buffer), "%d", pin);
    if (write(fd, buffer, len) < 0) {
        fprintf(stderr, "Failed to export gpio %d\n", pin);
        close(fd);
        return -1;
    }
    
    close(fd);
    
    // 等待sysfs文件系统创建GPIO目录
    usleep(100000); // 100ms
    
    return 0;
}

// GPIO取消导出函数
int gpio_unexport(int pin) {
    char buffer[64];
    int fd, len;
    
    if (!gpio_is_exported(pin)) {
        return 0; // 没有导出
    }
    
    fd = open(GPIO_UNEXPORT_PATH, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open unexport for writing\n");
        return -1;
    }
    
    len = snprintf(buffer, sizeof(buffer), "%d", pin);
    if (write(fd, buffer, len) < 0) {
        fprintf(stderr, "Failed to unexport gpio %d\n", pin);
        close(fd);
        return -1;
    }
    
    close(fd);
    return 0;
}

// 设置GPIO方向
int gpio_set_direction(int pin, const char* direction) {
    char path[64];
    int fd;
    
    snprintf(path, sizeof(path), "%s%d/direction", GPIO_BASE_PATH, pin);
    
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open gpio %d direction for writing\n", pin);
        return -1;
    }
    
    if (write(fd, direction, strlen(direction)) < 0) {
        fprintf(stderr, "Failed to set direction for gpio %d\n", pin);
        close(fd);
        return -1;
    }
    
    close(fd);
    return 0;
}

// 设置GPIO值
int gpio_set_value(int pin, int value) {
    char path[64];
    char value_str[2];
    int fd;
    
    snprintf(path, sizeof(path), "%s%d/value", GPIO_BASE_PATH, pin);
    snprintf(value_str, sizeof(value_str), "%d", value ? 1 : 0);
    
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open gpio %d value for writing\n", pin);
        return -1;
    }
    
    if (write(fd, value_str, 1) < 0) {
        fprintf(stderr, "Failed to set value for gpio %d\n", pin);
        close(fd);
        return -1;
    }
    
    close(fd);
    return 0;
}

// 获取GPIO值
int gpio_get_value(int pin) {
    char path[64];
    char value_str[3];
    int fd, value;
    
    snprintf(path, sizeof(path), "%s%d/value", GPIO_BASE_PATH, pin);
    
    fd = open(path, O_RDONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open gpio %d value for reading\n", pin);
        return -1;
    }
    
    if (read(fd, value_str, 2) < 0) {
        fprintf(stderr, "Failed to read value from gpio %d\n", pin);
        close(fd);
        return -1;
    }
    
    close(fd);
    value = atoi(value_str);
    return value;
}

// 设置GPIO边缘触发
int gpio_set_edge(int pin, const char* edge) {
    char path[64];
    int fd;
    
    snprintf(path, sizeof(path), "%s%d/edge", GPIO_BASE_PATH, pin);
    
    fd = open(path, O_WRONLY);
    if (fd < 0) {
        fprintf(stderr, "Failed to open gpio %d edge for writing\n", pin);
        return -1;
    }
    
    if (write(fd, edge, strlen(edge)) < 0) {
        fprintf(stderr, "Failed to set edge for gpio %d\n", pin);
        close(fd);
        return -1;
    }
    
    close(fd);
    return 0;
}

// 检查GPIO是否已导出
int gpio_is_exported(int pin) {
    char path[64];
    struct stat st;
    
    snprintf(path, sizeof(path), "%s%d", GPIO_BASE_PATH, pin);
    
    return (stat(path, &st) == 0);
}

// 初始化网络状态控制引脚
int init_network_pins(void) {
    int pins[] = {
        WIFI_EN_PIN, WIFI_RST_PIN, ETHERNET_RST_PIN,
        DISPLAY1_STATUS_PIN, DISPLAY1_READY_PIN,
        DISPLAY2_STATUS_PIN, DISPLAY2_READY_PIN,
        LED_NETWORK_PIN
    };
    int num_pins = sizeof(pins) / sizeof(pins[0]);
    int i;
    
    for (i = 0; i < num_pins; i++) {
        if (gpio_export(pins[i]) < 0) {
            fprintf(stderr, "Failed to export network pin %d\n", pins[i]);
            return -1;
        }
        
        if (gpio_set_direction(pins[i], GPIO_DIRECTION_OUT) < 0) {
            fprintf(stderr, "Failed to set direction for network pin %d\n", pins[i]);
            return -1;
        }
        
        // 设置初始状态
        if (pins[i] == WIFI_EN_PIN) {
            gpio_set_value(pins[i], 1); // WiFi使能
        } else if (pins[i] == LED_NETWORK_PIN) {
            gpio_set_value(pins[i], 0); // 网络LED初始关闭
        } else {
            gpio_set_value(pins[i], 0); // 其他引脚初始为低电平
        }
    }
    
    return 0;
}

// 初始化传感器引脚
int init_sensor_pins(void) {
    int input_pins[] = {
        TEMP_SENSOR_INT_PIN, HUMIDITY_SENSOR_INT_PIN, 
        LIGHT_SENSOR_INT_PIN //, MOTION_SENSOR_PIN // 运动检测已删除
    };
    int num_input_pins = sizeof(input_pins) / sizeof(input_pins[0]);
    int i;
    
    for (i = 0; i < num_input_pins; i++) {
        if (gpio_export(input_pins[i]) < 0) {
            fprintf(stderr, "Failed to export sensor pin %d\n", input_pins[i]);
            return -1;
        }
        
        if (gpio_set_direction(input_pins[i], GPIO_DIRECTION_IN) < 0) {
            fprintf(stderr, "Failed to set direction for sensor pin %d\n", input_pins[i]);
            return -1;
        }
        
        // 为中断引脚设置边缘触发
        // if (input_pins[i] != MOTION_SENSOR_PIN) { // 运动检测已删除
            gpio_set_edge(input_pins[i], GPIO_EDGE_FALLING);
        // } else {
        //     gpio_set_edge(input_pins[i], GPIO_EDGE_RISING);
        // }
    }
    
    return 0;
}

// 初始化LED控制引脚
int init_led_pins(void) {
    int led_pins[] = {LED_PWR_PIN, LED_STATUS_PIN, LED_ERROR_PIN, LED_NETWORK_PIN};
    int num_led_pins = sizeof(led_pins) / sizeof(led_pins[0]);
    int i;
    
    for (i = 0; i < num_led_pins; i++) {
        if (gpio_export(led_pins[i]) < 0) {
            fprintf(stderr, "Failed to export LED pin %d\n", led_pins[i]);
            return -1;
        }
        
        if (gpio_set_direction(led_pins[i], GPIO_DIRECTION_OUT) < 0) {
            fprintf(stderr, "Failed to set direction for LED pin %d\n", led_pins[i]);
            return -1;
        }
        
        // 初始化LED状态
        if (led_pins[i] == LED_PWR_PIN) {
            gpio_set_value(led_pins[i], 1); // 电源LED常亮
        } else {
            gpio_set_value(led_pins[i], 0); // 其他LED关闭
        }
    }
    
    return 0;
}

// 设置网络状态LED
int set_network_status_led(int status) {
    switch (status) {
        case NETWORK_STATUS_DISCONNECTED:
            return gpio_set_value(LED_NETWORK_PIN, 0); // 关闭
        case NETWORK_STATUS_CONNECTING:
            // 可以实现闪烁逻辑，这里简化为常亮
            return gpio_set_value(LED_NETWORK_PIN, 1);
        case NETWORK_STATUS_CONNECTED:
            return gpio_set_value(LED_NETWORK_PIN, 1); // 常亮
        case NETWORK_STATUS_ERROR:
            // 可以实现快速闪烁逻辑，这里简化为关闭
            return gpio_set_value(LED_NETWORK_PIN, 0);
        default:
            return -1;
    }
}

// 获取显示设备状态
int get_display_status(int display_index) {
    int status_pin = (display_index == 0) ? DISPLAY1_STATUS_PIN : DISPLAY2_STATUS_PIN;
    return gpio_get_value(status_pin);
}

// 控制WiFi模块
int wifi_control(int enable) {
    if (enable) {
        // 先复位WiFi模块
        gpio_set_value(WIFI_RST_PIN, 0);
        usleep(100000); // 100ms
        gpio_set_value(WIFI_RST_PIN, 1);
        usleep(500000); // 500ms
        
        // 使能WiFi
        return gpio_set_value(WIFI_EN_PIN, 1);
    } else {
        // 禁用WiFi
        gpio_set_value(WIFI_EN_PIN, 0);
        return gpio_set_value(WIFI_RST_PIN, 0);
    }
}

// 控制以太网模块
int ethernet_control(int enable) {
    if (enable) {
        // 复位以太网模块
        gpio_set_value(ETHERNET_RST_PIN, 0);
        usleep(100000); // 100ms
        return gpio_set_value(ETHERNET_RST_PIN, 1);
    } else {
        return gpio_set_value(ETHERNET_RST_PIN, 0);
    }
}

// 控制状态LED
int set_status_led(int led_type, int value) {
    int pin;
    
    switch (led_type) {
        case 0: pin = LED_PWR_PIN; break;
        case 1: pin = LED_STATUS_PIN; break;
        case 2: pin = LED_ERROR_PIN; break;
        case 3: pin = LED_NETWORK_PIN; break;
        default: return -1;
    }
    
    return gpio_set_value(pin, value);
}

// 读取传感器中断状态
int read_sensor_interrupt(int sensor_type) {
    int pin;
    
    switch (sensor_type) {
        case 0: pin = TEMP_SENSOR_INT_PIN; break;
        case 1: pin = HUMIDITY_SENSOR_INT_PIN; break;
        case 2: pin = LIGHT_SENSOR_INT_PIN; break;
        default: return -1;
    }
    
    return gpio_get_value(pin);
}

// 清理所有GPIO
int cleanup_all_gpio(void) {
    int all_pins[] = {
        WIFI_EN_PIN, WIFI_RST_PIN, ETHERNET_RST_PIN,
        DISPLAY1_STATUS_PIN, DISPLAY1_READY_PIN,
        DISPLAY2_STATUS_PIN, DISPLAY2_READY_PIN,
        TEMP_SENSOR_INT_PIN, HUMIDITY_SENSOR_INT_PIN,
        LIGHT_SENSOR_INT_PIN,
        LED_PWR_PIN, LED_STATUS_PIN, LED_ERROR_PIN, LED_NETWORK_PIN
    };
    int num_pins = sizeof(all_pins) / sizeof(all_pins[0]);
    int i;
    
    for (i = 0; i < num_pins; i++) {
        gpio_unexport(all_pins[i]);
    }
    
    return 0;
} 